package com.itheima.service.impl;

import com.itheima.common.utils.DateUtils;
import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.pojo.*;
import com.itheima.service.ReportService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 会员数量统计
     * @return
     */
    @Override
    public MemberReportVO getMemberReport() {
        //获取往前一年的时间
        List<Date> minOfMonth = new ArrayList<>();
        List<Date> maxOfMonth = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,1);
        minOfMonth.add(calendar.getTime());
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        maxOfMonth.add(calendar.getTime());
        for (int i = 0; i < 11; i++) {
            calendar.add(Calendar.MONTH,-1);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            minOfMonth.add(calendar.getTime());
            calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            maxOfMonth.add(calendar.getTime());
        }
        //获取每月的会员数
        List<Integer> memberCount = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            memberCount.add(memberMapper.getMemberCountByDate(minOfMonth.get(i),maxOfMonth.get(i)));
        }

        //时间格式化
        List<String> months = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (Date date : maxOfMonth) {
            months.add(sdf.format(date));
        }

        return MemberReportVO.builder()
                .months(months)
                .memberCount(memberCount)
                .build();
    }

    /**
     * 套餐数量统计
     * @return
     */
    @Override
    public SetmealReportVO getSetmealReport() {
        List<SetmealVO> setmeals = orderMapper.getReport();
        //封装给前端
        List<String> setmealNames = new ArrayList<>();
        for (SetmealVO setmealVO : setmeals) {
            setmealNames.add(setmealVO.getName());
        }
        SetmealReportVO setmealReportVO = SetmealReportVO.builder()
                .setmealNames(setmealNames)
                .setmealCounts(setmeals)
                .build();
        return setmealReportVO;
    }

    /**
     * 获取营业数据
     * @return
     */
    @Override
    public BusinessReportVO getBusinessReport() {
//        private Integer todayNewMember;//今日新增会员数
        Integer todayNewMember = memberMapper.findMemberCountByDate(DateUtils.getToday());
//        private Integer totalMember;//总会员数
        Integer totalMember = memberMapper.findMemberCountByDate(null);
//        private Integer thisWeekNewMember;//本周新增会员数
        Date week = DateUtils.getThisWeekMonday();
        Integer thisWeekNewMember = memberMapper.findMemberCountByDate(week);
//        private Integer thisMonthNewMember;//本月新增会员数
        Date month = DateUtils.getFirstDay4ThisMonth();
        Integer thisMonthNewMember = memberMapper.findMemberCountByDate(month);
//        private Integer todayOrderNumber;//今日预约数
        Integer todayOrderNumber = orderMapper.findOrderCountByDate(DateUtils.getToday(),null);
//        private Integer todayVisitsNumber;//今日到诊数
        Integer todayVisitsNumber = orderMapper.findOrderCountByDate(DateUtils.getToday(), Order.ORDERSTATUS_YES);
//        private Integer thisWeekOrderNumber;//本周预约数
        Integer thisWeekOrderNumber = orderMapper.findOrderCountByDate(week, null);
//        private Integer thisWeekVisitsNumber;//本周预约数
        Integer thisWeekVisitsNumber = orderMapper.findOrderCountByDate(week, Order.ORDERSTATUS_YES);
//        private Integer thisMonthOrderNumber;//本月预约数
        Integer thisMonthOrderNumber = orderMapper.findOrderCountByDate(month, null);
//        private Integer thisMonthVisitsNumber;//本月到诊数
        Integer thisMonthVisitsNumber = orderMapper.findOrderCountByDate(month, Order.ORDERSTATUS_YES);

        //热门套餐封装
        List<SetmealVO> setmealVOS = orderMapper.getReport();
        List<HotSetmeal> list = new ArrayList<>();
        Integer setmeal_count = orderMapper.findOrderCountByDate(null,null);
        for (SetmealVO setmealVO : setmealVOS) {
            HotSetmeal hotSetmeal = HotSetmeal.builder()
                    .name(setmealVO.getName())
                    .setmeal_count(setmealVO.getValue())
                    .proportion(setmealVO.getValue() * 1.0000f / setmeal_count)
                    .build();
            list.add(hotSetmeal);
            //只统计前五
            if(list.size() == 5){
                break;
            }
        }
        BusinessReportVO businessReportVO = BusinessReportVO.builder()
                .reportDate(LocalDate.now())
                .todayNewMember(todayNewMember)
                .totalMember(totalMember)
                .thisWeekNewMember(thisWeekNewMember)
                .thisMonthNewMember(thisMonthNewMember)
                .todayOrderNumber(todayOrderNumber)
                .todayVisitsNumber(todayVisitsNumber)
                .thisWeekOrderNumber(thisWeekOrderNumber)
                .thisWeekVisitsNumber(thisWeekVisitsNumber)
                .thisMonthOrderNumber(thisMonthOrderNumber)
                .thisMonthVisitsNumber(thisMonthVisitsNumber)
                .hotSetmeal(list)
                .build();
        return businessReportVO;
    }

    /**
     * 导出报表
     * @param response
     * @param reportVO
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response, BusinessReportVO reportVO) {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheet("sheet1");
            sheet.getRow(2).getCell(5).setCellValue(reportVO.getReportDate().toString());
            sheet.getRow(4).getCell(5).setCellValue(reportVO.getTodayNewMember());
            sheet.getRow(4).getCell(7).setCellValue(reportVO.getTotalMember());
            sheet.getRow(5).getCell(5).setCellValue(reportVO.getThisWeekNewMember());
            sheet.getRow(5).getCell(7).setCellValue(reportVO.getThisMonthNewMember());
            sheet.getRow(7).getCell(5).setCellValue(reportVO.getTodayOrderNumber());
            sheet.getRow(7).getCell(7).setCellValue(reportVO.getTodayVisitsNumber());
            sheet.getRow(8).getCell(5).setCellValue(reportVO.getThisWeekOrderNumber());
            sheet.getRow(8).getCell(7).setCellValue(reportVO.getThisWeekVisitsNumber());
            sheet.getRow(9).getCell(5).setCellValue(reportVO.getThisMonthOrderNumber());
            sheet.getRow(9).getCell(7).setCellValue(reportVO.getThisMonthVisitsNumber());

            List<HotSetmeal> hotSetmeal = reportVO.getHotSetmeal();
            for (int i = 0; i < hotSetmeal.size(); i++) {
                XSSFRow row = sheet.getRow(12+i);
                row.getCell(4).setCellValue(hotSetmeal.get(i).getName());
                row.getCell(5).setCellValue(hotSetmeal.get(i).getSetmeal_count());
                row.getCell(6).setCellValue(hotSetmeal.get(i).getProportion());
            }
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            out.flush();
            out.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
